package org.jeecg.modules.wms.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.wms.entity.WmsWarehouseLocation;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 库位信息服务接口
 */
public interface IWmsWarehouseLocationService extends IService<WmsWarehouseLocation> {

    /**
     * 根据仓库ID查询库位列表
     *
     * @param warehouseId 仓库ID
     * @return 库位列表
     */
    List<WmsWarehouseLocation> queryLocationListByWarehouseId(String warehouseId);

    /**
     * 添加库位信息
     *
     * @param wmsWarehouseLocation 库位信息
     * @return 是否成功
     */
    boolean saveLocation(WmsWarehouseLocation wmsWarehouseLocation);

    /**
     * 修改库位信息
     *
     * @param wmsWarehouseLocation 库位信息
     * @return 是否成功
     */
    boolean updateLocation(WmsWarehouseLocation wmsWarehouseLocation);

    /**
     * 删除库位信息
     *
     * @param id 库位ID
     * @return 是否成功
     */
    boolean deleteLocation(String id);

    /**
     * 批量删除库位信息
     *
     * @param ids 库位ID集合
     * @return 是否成功
     */
    boolean batchDeleteLocation(String ids);

    /**
     * 生成库位二维码
     *
     * @param id 库位ID
     * @return 二维码路径
     */
    String generateLocationQrcode(String id);

    /**
     * 批量生成库位二维码
     *
     * @param warehouseId 仓库ID
     * @return 是否成功
     */
    boolean batchGenerateLocationQrcode(String warehouseId);
    
    /**
     * 批量生成库位
     *
     * @param warehouseId 仓库ID
     * @param codePrefix 库位编号前缀
     * @param namePrefix 库位名称前缀
     * @param startNum 起始编号
     * @param count 生成数量
     * @param numLength 编号位数
     * @param status 状态
     * @param remark 备注
     * @return 生成成功的库位数量
     */
    int batchGenerateLocation(String warehouseId, String codePrefix, String namePrefix, Integer startNum, Integer count, Integer numLength, String status, String remark);
    
    /**
     * 查询导出数据列表
     * 
     * @param wmsWarehouseLocation 查询条件
     * @param parameterMap 请求参数
     * @return 导出数据列表
     */
    List<WmsWarehouseLocation> queryExportList(WmsWarehouseLocation wmsWarehouseLocation, Map<String, String[]> parameterMap);
    
    /**
     * 导出Excel
     * 
     * @param request 请求对象
     * @param pageList 数据列表
     * @param clazz 实体类
     * @param title 标题
     * @param excludeColumns 排除的列
     * @return ModelAndView
     */
    ModelAndView exportXls(HttpServletRequest request, List<WmsWarehouseLocation> pageList, Class<WmsWarehouseLocation> clazz, String title, List<String> excludeColumns);

    /**
     * 重写page方法，在查询结果中填充仓库名称
     * 
     * @param page 分页对象
     * @param queryWrapper 查询条件
     * @return 分页结果
     */
    IPage<WmsWarehouseLocation> getByList(Page<WmsWarehouseLocation> page, QueryWrapper<WmsWarehouseLocation> queryWrapper);

    /**
     * 导出Excel（流式导出）
     * 
     * @param response HttpServletResponse响应对象
     * @param pageList 导出数据列表
     * @param title 导出文件标题
     * @throws IOException IO异常
     */
    void exportXlsStream(HttpServletResponse response, List<WmsWarehouseLocation> pageList, String title) throws IOException;
    
    /**
     * 查询空库位
     *
     * @param warehouseId 仓库ID
     * @return 空库位列表
     */
    List<WmsWarehouseLocation> queryEmptyLocations(String warehouseId);

    /**
     * 查询可用库位（状态为0-空闲或1-占用但未满的库位）
     * @param warehouseId 仓库ID
     * @return 可用库位列表
     */
    List<WmsWarehouseLocation> queryAvailableLocations(String warehouseId);

    /**
     * 查询未满的库位（状态为1-占用但未满的库位），按物料编号匹配
     * @param warehouseId 仓库ID
     * @param materialCode 物料编号
     * @return 未满库位列表
     */
    List<WmsWarehouseLocation> queryPartiallyOccupiedLocations(String warehouseId, String materialCode);

    /**
     * 获取未完成入库单中已分配的库位信息
     * @return Map<库位ID, 物料编码>
     */
    Map<String, String> getPendingAllocatedLocations();
} 